import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User as UserEntity } from './entities/user.entity';
import { DeepPartial, Repository } from 'typeorm';
import { TypeOrmCrudService } from '@dataui/crud-typeorm';
import { CrudRequest } from '@dataui/crud';
import { getPassword } from '@/utils/password';
import { Role } from '@/role/entities/role.entity';
import { Permission } from '@/permission/entities/permission.entity';
import { PermissionApi } from '@/permission/entities/permission-api.entity';
import { CreatePermissionDto } from '@/permission/dto/create-permission.dto';
import { TestingMachine } from '@/testing-machine/entities/testing-machine.entity';

export type User = {
  id: number;
  userName: string;
  password: string;
  desc: string;
  roles: string[];
};

@Injectable()
export class UserService extends TypeOrmCrudService<UserEntity> {
  constructor(
    @InjectRepository(UserEntity)
    private readonly userRepo: Repository<UserEntity>,
    @InjectRepository(Permission)
    private readonly permissionRepo: Repository<Permission>,
    @InjectRepository(Role)
    private readonly roleRepo: Repository<Role>,
    @InjectRepository(TestingMachine)
    private readonly testingMachineRepo: Repository<TestingMachine>,
  ) {
    super(userRepo);
  }

  async createOne(
    req: CrudRequest,
    dto: DeepPartial<UserEntity>,
  ): Promise<UserEntity> {
    dto.password = await getPassword(dto.password);
    return super.createOne(req, dto);
  }

  async initRole(): Promise<any> {
    const role = new Role();
    role.name = 'station';
    role.remark = '测报站';
    const roleResult = await this.roleRepo.save(role);

    const users = [
      {
        speciesName: ['斯氏鼢鼠', '松针小卷蛾'],
        userName: '吴起县森林病虫害防治检疫站',
      },
      {
        speciesName: ['春尺蛾', '中华鼢鼠'],
        userName: '延安市安塞区林业工作站',
      },
      {
        speciesName: ['松梢螟', '柏大蚜'],
        userName: '铜川市耀州区森林病虫害防治检疫站',
      },
      {
        speciesName: ['猕猴桃溃疡病', '杨树天牛类', '杨树食叶害虫'],
        userName: '杨陵区林业工作站',
      },
      {
        speciesName: ['油松毛虫', '花椒窄吉丁'],
        userName: '韩城市林木病虫防治检疫站',
      },
      {
        speciesName: ['杨小舟蛾', '核桃黑斑病'],
        userName: '西安市鄠邑区森林资源管理中心',
      },
      {
        speciesName: ['光肩星天牛', '杨扇舟蛾'],
        userName: '兴平市森林病虫害防治检疫站',
      },
      {
        speciesName: ['光肩星天牛', '花椒窄古丁'],
        userName: '富平县林木病虫害防治检疫站',
      },
      {
        speciesName: ['松阿扁叶蜂', '核桃吉丁'],
        userName: '山阳县林木病虫害防治站',
      },
      {
        speciesName: ['松褐天牛', '板栗瘿蜂'],
        userName: '镇安县森林病虫害防治检疫站',
      },
      {
        speciesName: ['柳毒蛾', '枣飞象'],
        userName: '神木市森林防火指挥部办公室',
      },
      {
        speciesName: ['中华鼢鼠', '板栗疫病'],
        userName: '商南县森林病虫害防治检疫站',
      },
      { speciesName: ['国槐尺蟻', '中华鼢鼠'], userName: '长武县林业工作站' },
      {
        speciesName: ['柑桔大实蝇', '核桃举肢蛾'],
        userName: '甸阳县森林病虫害防治检疫站',
      },
      {
        speciesName: ['白杨透翅蛾', '杨树溃疡病'],
        userName: '华阴市林业工作站',
      },
      {
        speciesName: ['杏球蚧', '松针小卷蛾'],
        userName: '榆林市榆阳区林业工作站',
      },
      {
        speciesName: ['光肩星天牛', '丝绵木金星尺蛾'],
        userName: '略阳县森林病虫防治检疫站',
      },
      {
        speciesName: ['红脂大小蠢', '油松毛虫'],
        userName: '延安市黄龙山林业局森林病虫害防治站',
      },
      {
        speciesName: ['华山松大小蠢', '光肩星天牛'],
        userName: '眉县林木病虫防治检疫站',
      },
      {
        speciesName: ['松梢螟', '核桃叶甲'],
        userName: '宜君县森林病虫害防治检疫工作站',
      },
      {
        speciesName: ['松阿扁叶蜂', '侧柏叶枯病'],
        userName: '扶风县林木病虫防治检疫站',
      },
      {
        speciesName: ['中华鼢鼠', '桃小食心虫'],
        userName: '彬县森林病虫害防治检疫站',
      },
      {
        speciesName: ['斯氏盼鼠', '春尺蛾'],
        userName: '延长县森林病虫防治检疫站',
      },
      {
        speciesName: ['云南松毛虫', '杜仲梦尼夜蛾'],
        userName: '宁强县森林病虫防治站',
      },
      {
        speciesName: ['松阿扁叶蜂', '核桃举肢蛾'],
        userName: '洛南县森林病虫害防治检疫站',
      },
      {
        speciesName: ['油松毛虫', '华山松大小蠹'],
        userName: '陕西省宁西林业局森林病虫害监测防治检疫站',
      },
      {
        speciesName: ['中华鼢鼠', '华山松大小蠹'],
        userName: '平利县森林病虫害防治检疫站',
      },
      {
        speciesName: ['油松毛虫', '核桃举肢蛾'],
        userName: '蓝田县森林病虫害防治检疫站',
      },
      {
        speciesName: ['红脂大小蠹', '国槐尺蠖'],
        userName: '甸邑县森林病虫害防治检疫站',
      },
      {
        speciesName: ['舞毒蛾', '白杨透翅蛾'],
        userName: '潼关县林木病虫防治检疫站',
      },
      {
        speciesName: ['云斑天牛', '银杏大蚕蛾'],
        userName: '洋县森林病虫防治检疫站',
      },
      {
        speciesName: ['松褐天牛', '核桃叶甲'],
        userName: '安康市汉滨区森林病虫害防治检疫站',
      },
      {
        speciesName: ['华山松大小蠹', '板栗瘿蜂'],
        userName: '宁陕县森林病虫害防治检疫站',
      },
      {
        speciesName: ['杨扇舟蛾', '松阿扁叶蜂'],
        userName: '汉中市南郑区森林病虫防治检疫站',
      },
      {
        speciesName: ['春尺蛾', '核桃长足象'],
        userName: '镇巴县森林病虫防治检疫站',
      },
    ] as UserEntity[];
    for (let i = 0; i < users.length; i++) {
      users[i].roles = [roleResult];
      // users[i].speciesName = '虫体' + i;
      // users[i].userName = "aa";
      users[i].password = await getPassword(users[i].userName);
      await this.userRepo.save(users[i]);
    }
  }

  async addCityUsers(req: CrudRequest, dto: DeepPartial<CreatePermissionDto>) {
    const cityRole = await this.roleRepo.findOne({
      where: {
        name: 'city',
      },
    });
    const cityUsers = [
      {
        companyLabel: '西安市',
        userName: '610100',
        companyType: 'city',
        speciesName: [],
      },
      {
        companyLabel: '铜川市',
        userName: '610200',
        companyType: 'city',
        speciesName: [],
      },
      {
        companyLabel: '宝鸡市',
        userName: '610300',
        companyType: 'city',
        speciesName: [],
      },
      {
        companyLabel: '咸阳市',
        userName: '610400',
        companyType: 'city',
        speciesName: [],
      },
      {
        companyLabel: '渭南市',
        userName: '610500',
        companyType: 'city',
        speciesName: [],
      },
      {
        companyLabel: '延安市',
        userName: '610600',
        companyType: 'city',
        speciesName: [],
      },
      {
        companyLabel: '汉中市',
        userName: '610700',
        companyType: 'city',
        speciesName: [],
      },
      {
        companyLabel: '榆林市',
        userName: '610800',
        companyType: 'city',
        speciesName: [],
      },
      {
        companyLabel: '安康市',
        userName: '610900',
        companyType: 'city',
        speciesName: [],
      },
      {
        companyLabel: '商洛市',
        userName: '611000',
        companyType: 'city',
        speciesName: [],
      },
    ] as UserEntity[];
    for (let i = 0; i < cityUsers.length; i++) {
      cityUsers[i].roles = [cityRole];
      cityUsers[i].password = await getPassword('asd123456');
      await this.userRepo.save(cityUsers[i]);
    }
  }

  async addCityUsersRole(
    req: CrudRequest,
    dto: DeepPartial<CreatePermissionDto>,
  ) {
    const role = await this.roleRepo.findOne({
      where: {
        id: 25,
      },
      relations: ['permissions'],
    });

    const city = new Role();
    city.permissions = role.permissions;
    city.name = 'city';
    city.remark = '城市管理员';
    this.roleRepo.save(city);
  }

  async addAdminRole() {
    const role = await this.roleRepo.findOne({
      where: {
        id: 25,
      },
      relations: ['permissions'],
    });
    const admin = new Role();
    admin.permissions = role.permissions;
    admin.name = 'admin';
    admin.remark = '超级管理员';
    this.roleRepo.save(admin);
  }

  async initUsers(
    req: CrudRequest,
    dto: DeepPartial<UserEntity>,
  ): Promise<any> {
    const user = await this.userRepo.findOneBy({
      id: 1,
    });
    await this.userRepo.save([user]);
    user.userName = 'aa';
    user.roles;
    const result = await this.userRepo.remove(user);
    return result;
  }

  async handleRoleAndPermission(
    req: CrudRequest,
    dto: DeepPartial<UserEntity>,
  ): Promise<any> {
    // 拿到一个id为1的用户
    const user = await this.userRepo.findOneBy({
      id: 1,
    });
    user.userName = 'lalala';
    // user.createTime = new Date();
    // 创建一个角色
    const role = new Role();
    role.name = 'admin';
    role.remark = '超级管理员';

    // 给角色添加权限
    // 创建权限
    // const permission1 = new Permission();
    // permission1.name = '用户信息';
    // permission1.type = 'api';
    // permission1.code = 'getUserInfo';
    //
    // const permissionApi1 = new PermissionApi();
    // permissionApi1.apiUrl = '/api/getUserInfo';
    // permissionApi1.apiMethod = 'GET';
    // permission1.permissionApi = permissionApi1;
    const permission1 = new Permission();
    permission1.name = '创建测报机';
    permission1.type = 'api';
    permission1.code = 'createTestingMachine';
    const permissionApi1 = new PermissionApi();
    permissionApi1.apiUrl = '/api/testing-machine';
    permissionApi1.apiMethod = 'POST';
    permission1.permissionApi = permissionApi1;

    role.permissions = [permission1];

    const role2 = new Role();
    role2.name = 'user';
    role2.remark = '普通用户';
    role2.permissions = [permission1];

    user.roles = [role, role2];

    // 给用户添加角色
    console.log(user);

    console.log(req, dto);
    // 保存用户
    await this.userRepo.save(user);
    return;
  }

  async addTestingMachine() {
    const users = await this.userRepo.find({
      order: {
        id: 'asc',
      },
    });
    for (let i = 0; i < users.length; i++) {
      const user = users[i];
      const testingMachine = new TestingMachine();
      testingMachine.machineName = user.userName;
      testingMachine.machineAddress = '待定';
      testingMachine.machineWifi = 1;
      testingMachine.machineStatus = 1;
      testingMachine.user = user;
      await this.testingMachineRepo.save(testingMachine);
    }
  }

  async addPermission(req: CrudRequest, dto: DeepPartial<CreatePermissionDto>) {
    const role = await this.roleRepo.findOneBy({ name: 'station' });
    const role2 = await this.roleRepo.findOneBy({ name: 'admin' });
    const permission = new Permission();
    const permissionApi = new PermissionApi();

    permissionApi.apiMethod = dto.method;
    permissionApi.apiUrl = dto.url;

    permission.type = dto.type;
    permission.code = dto.code;
    permission.name = dto.name;
    permission.roles = [role, role2];
    permission.permissionApi = permissionApi;

    const result = await this.permissionRepo.save(permission);
    return result;
  }

  // async getMyTestingMachine()
}
